package com.bbs.toutiao.controller.client;


import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import com.bbs.toutiao.aspect.SysLog;
import com.bbs.toutiao.exception.BaseException;
import com.bbs.toutiao.exception.ExceptionEnum;
import com.bbs.toutiao.mapper.clinet.ClientChatMapper;
import com.bbs.toutiao.service.client.impl.SseServiceImpl;
import com.bbs.toutiao.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.websocket.server.PathParam;


/**
 * 描述:  sse单向推送
 * 作者： zhangBin
 * 时间： 2024/4/2 14:18
 * 版本： 1.0
 */

@Slf4j
@RestController
@RequestMapping("/sse")
public class SseController {

    @Resource
    SseServiceImpl sseService;

    @Resource
    ClientChatMapper clientChatMapper;


    //sse推送
//    @CrossOrigin
    @GetMapping(value = "/createSse",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter sse(
            @PathParam("token") String token,
                          HttpServletResponse response) {
        String userId;
        try {
            JWT jwt = JWTUtil.parseToken(token);
            userId = jwt.getPayload("userId").toString();
        } catch (Exception e) {
            throw new BaseException(ExceptionEnum.TOKEN_FONT_ERROR);
        }
        response.setContentType("text/event-stream; charset=UTF-8");
        return sseService.createSse(userId);
    }

    //发送消息
    @SysLog("用户发送消息")
    @GetMapping(value = "/sendMsg")
    public Result sseChat(@PathParam("uid") int uid,
                          @PathParam("content") String content,
                          @PathParam("imgUrl") String imgUrl,
                          @PathParam("uuid") String uuid,
                          @PathParam("receiverId") int receiverId) {
        log.info("uid:{},content:{},toUid:{},imgUrl", uid, content, receiverId);
        if (StrUtil.isBlank(content) && StrUtil.isBlank(imgUrl)) {
            throw new BaseException(ExceptionEnum.MSG_ERROR);
        }
        if (sseService.sendMessage(uid, content, uuid, imgUrl, receiverId)) {
            return Result.success("发送成功");
        }
        return Result.error(404, "发送失败");
    }

    /**
     * 查询聊天记录（根据时间段查询）
     *
     * @param uid
     * @param toUid
     * @param time
     * @param timeEnd
     * @return
     */
    @GetMapping("/chat/{uid}")
    public Result getChatAll(@PathVariable("uid") int uid,
                             @PathParam("toUid") int toUid,
                             @PathParam("time") String time,
                             @PathParam("timeEnd") String timeEnd) {
        try {
            Assert.notBlank(time, "开始时间不能为空");
            Assert.notBlank(timeEnd, "结束时间不能为空");
            Assert.isTrue(uid > 0, "用户id必须大于0");
            Assert.isTrue(toUid > 0, "用户id必须大于0");
        } catch (Exception e) {
            throw new BaseException(400, e.getMessage());
        }
        return Result.success("g", sseService.queryMessage(time, timeEnd, uid, toUid));
    }

    //查询消息单个用户
    @SysLog("查询消息单个用户")
    @GetMapping("/getChatMsg/{uid}/{toUid}")
    public Result getChatByUid(@PathVariable("uid") Integer uid,
                               @PathVariable("toUid") Integer toUid) {
        return Result.success("发送成功", clientChatMapper.selectChatByUserIdNews(uid, toUid));
    }

    /**
     * @param uid
     * @param toUid
     * @param page
     * @param size
     * @return
     */
    @SysLog("分页查询聊天消息")
    @GetMapping("/getChatByPage/{uid}/{toUid}/{page}/{size}")
    public Result getByPage(@PathVariable("uid") Integer uid,
                            @PathVariable("toUid") Integer toUid,
                            @PathVariable("page") Integer page,
                            @PathVariable("size") Integer size) {
        try {
            Assert.notNull(page, "页数不能为空");
            Assert.notNull(size, "每页条数不能为空");
            Assert.isTrue(uid > 0, "用户id必须大于0");
            Assert.isTrue(toUid > 0, "用户id必须大于0");
        } catch (Exception e) {
            throw new BaseException(400, e.getMessage());
        }
        int pageSize = (page - 1) * size;
//        log.info(pageSize + " " + size);
        // 查询
        return Result.success("查询成功", sseService.queryMessageByPage(pageSize, size, uid, toUid));
    }


    /**
     * 查询用户关注的人（好友）
     *
     * @param token
     * @return
     */
    @GetMapping("/getFollows")
    public Result getFollowsList(@RequestHeader String token, @PathParam("type") String type) {
        int userId;
        //获取请求头中的token解析出
        try {
            JWT jwt = JWTUtil.parseToken(token);
            userId = Integer.parseInt(jwt.getPayload("userId").toString());
        } catch (Exception e) {
            throw new BaseException(ExceptionEnum.TOKEN_FONT_ERROR);
        }

        return Result.success("查询成功", sseService.queryFollowsList(userId, type));
    }

    //已读
    @GetMapping("/updateIsRead/{toUid}")
    public Result updateIsRead(@RequestHeader String token, @PathVariable("toUid") Integer toUid) {
        int userId;
        //获取请求头中的token解析出
        try {
            JWT jwt = JWTUtil.parseToken(token);
            userId = Integer.parseInt(jwt.getPayload("userId").toString());
        } catch (Exception e) {
            throw new BaseException(ExceptionEnum.TOKEN_FONT_ERROR);
        }

        return sseService.readMessage(userId, toUid) ? Result.success("更新成功")
                : Result.error(300, "更新失败");
    }

    //清空聊天记录
    @GetMapping("/clearChatRecord")
    public Result clearChatRecord(@RequestHeader String token, @PathParam("toUid") Integer toUid) {
        int userId;
        //获取请求头中的token解析出
        try {
            JWT jwt = JWTUtil.parseToken(token);
            userId = Integer.parseInt(jwt.getPayload("userId").toString());
        } catch (Exception e) {
            throw new BaseException(ExceptionEnum.TOKEN_FONT_ERROR);
        }
        sseService.deleteMessage(userId, toUid);
        return Result.success("删除成功");
    }
}
